package com.wistech.search.solr.qp;

import java.io.StringReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.TextField;
import org.apache.solr.search.QParser;
import org.apache.solr.search.SolrQueryParser;

/**
 * 把 queryText 转为 and 关系的 queryparser.
 * 
 * @author Steven Liu
 * 
 * 
 */
public class ChineseSolrQueryParser extends SolrQueryParser {
	public ChineseSolrQueryParser(QParser parser, String defaultField,
			Analyzer analyzer) {
		super(parser, defaultField, analyzer);
	}

	public ChineseSolrQueryParser(QParser parser, String defaultField) {
		super(parser, defaultField);

	}

	protected Query getFieldQuery(String field, String queryText, boolean quoted)
			throws ParseException {
		BooleanClause.Occur occur = QueryParser.Operator.OR
				.equals(getDefaultOperator()) ? Occur.SHOULD : Occur.MUST;
		String qField = field == null ? defaultField : field;
		if (qField != null) {
			FieldType ft = schema.getField(qField).getType();
			if (ft instanceof TextField) {
				try {
					// 此字段的分词器
					Analyzer analyzer = ft.getQueryAnalyzer();
					if (analyzer == null) {
						analyzer = ft.getAnalyzer();
					}
					if (analyzer != null) {
						BooleanQuery bq = new BooleanQuery();
						TokenStream ts = analyzer.tokenStream(field,
								new StringReader(queryText));
						ts.reset();
						int endOffset = 0;
						while (ts.incrementToken()) {
							CharTermAttribute ta = (CharTermAttribute) ts
									.getAttribute(CharTermAttribute.class);
							OffsetAttribute oa = (OffsetAttribute) ts
									.getAttribute(OffsetAttribute.class);
							if (oa.startOffset() >= endOffset) {
								bq.add(new TermQuery(new Term(qField, ta
										.toString())), occur);
								endOffset = oa.endOffset();
							} else {
								bq.add(new TermQuery(new Term(qField, ta
										.toString())), occur);
							}
						}
						ts.close();
						return bq;
					}
				} catch (Exception e) {
					throw new ParseException(e.getMessage());
				}
			}
		}
		return super.getFieldQuery(field, queryText, quoted);
	}
}
